/*
 * Copyright 2007 Jeffrey Palm
 */

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;

final class MapquestDirections extends AbstractFinderIPod {

  public String name() {return "Mapquest";}

  class InputPanel extends JPanel {

    private JTextField   urlField  = new JTextField(40);
    private AddressPanel fromField = new AddressPanel(getClass() + ":from");
    private AddressPanel toField   = new AddressPanel(getClass() + ":to");

    private JPanel wrap(String title, Component c) {
      JPanel p = new JPanel();
      p.add(c);
      p.setBorder(BorderFactory.createTitledBorder(title));
      return p;
    }

    InputPanel() {
      setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
      add(new ImagePanel(name(),"http://img.mqcdn.com/mqsite/hdr-logo-mapquest"));
      add(Util.lp(new JLabel("Please provide a URL")));
      add(wrap("URL",urlField));
      add(new JLabel("-or- "));
      add(Util.lp(new JLabel("Provide 'from' and 'to' locations'")));
      add(wrap("From",fromField));
      add(wrap("To",toField));
      
    }

    public String getURL() { return urlField.getText().trim();}
    public AddressPanel getTo() { return toField;}
    public AddressPanel getFrom() { return fromField;}
  }

  class AddressPanel extends JPanel {
    private JTextField addressField = new TitledTextField("Address or Location",40);
    private JTextField cityField    = new TitledTextField("City",10);
    private JTextField stateField   = new TitledTextField("State",2);
    private JTextField zipcodeField = new TitledTextField("Zip code",9);
    private JCheckBox  rememberChk  = new JCheckBox();
    private final String prop;
    AddressPanel(String prop) {
      this.prop = prop;
      setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
      JPanel p;
      p = Util.xp();
      addressField.setText(Config.getInstance().get(prop + ":address"));
      p.add(addressField);
      add(p);
      p = Util.xp();
      cityField.setText(Config.getInstance().get(prop + ":city"));
      stateField.setText(Config.getInstance().get(prop + ":state"));
      zipcodeField.setText(Config.getInstance().get(prop + ":zipcode"));
      p.add(cityField);
      p.add(stateField);
      p.add(zipcodeField);
      add(p);
      p = new JPanel();
      p.setLayout(new FlowLayout(FlowLayout.LEFT));
      p.add(new JLabel("Remember"));
      rememberChk.setSelected(!isEmpty());
      p.add(rememberChk);
      add(p);
    }     
    public String getAddress() {return addressField.getText();}
    public String getCity() {return cityField.getText();}
    public String getState() {return stateField.getText();}
    public String getZipcode() {return zipcodeField.getText();}
    public boolean isEmpty() {
      return Util.isEmpty(getAddress())
        &&   Util.isEmpty(getCity())
        &&   Util.isEmpty(getState())
        &&   Util.isEmpty(getZipcode());
    }
    public void save() {
      if (rememberChk.isSelected()) {
        Config.getInstance().set(prop + ":address",getAddress());
        Config.getInstance().set(prop + ":city",getCity());
        Config.getInstance().set(prop + ":state",getState());
        Config.getInstance().set(prop + ":zipcode",getZipcode());
      } else {
        Config.getInstance().set(prop + ":address","");
        Config.getInstance().set(prop + ":city","");
        Config.getInstance().set(prop + ":state","");
        Config.getInstance().set(prop + ":zipcode","");
      }
    }
  }

  protected void findRest(IPod ipod, Progress p) throws Exception {
    //
    // Prompt for a URL
    //
    String url = null;
    InputPanel ip = new InputPanel();
    AddressPanel from = ip.getFrom();
    AddressPanel to = ip.getTo();
    do {
      int res = JOptionPane.showConfirmDialog(null, ip, "Directions", 
                                              JOptionPane.OK_CANCEL_OPTION,
                                              JOptionPane.QUESTION_MESSAGE,
                                              null);
      if (res == JOptionPane.CANCEL_OPTION) return;
      url = ip.getURL();
      to.save();
      from.save();
    } while (Util.isEmpty(url) && (to.isEmpty() || from.isEmpty()));

    if (Util.isEmpty(url)) {
      url = createURL(from,to);
    }

    if (url == null) return;

    PrintStream out = null;
    String outTitle = null;
    
    // For debugging we'll keep this open
    BufferedReader in = new BufferedReader(new InputStreamReader(open(url)));
    String line;
    String directions = null;
    String distance = null;
    String time = null;
    String title = null;
    String dist = null;
    boolean directionsNext = false;
    boolean distanceNext = false;
    int num = 1;
    while ((line = in.readLine()) != null) {

      line = line.trim();

      String target;
      int index;

      // <title>Driving Directions from 4416 Constance St, New Orleans, LA to 8250 N Grand Canyon Dr, Las Vegas, NV</title>
      target = "<title>Driving Directions from ";
      if (title == null && (index = line.indexOf(target)) != -1) {
        int ilt = line.indexOf("<",index+1);
        if (ilt != -1) {
          title = line.substring(index+target.length(),ilt).trim();
          //
          // Now find the title of the directions
          //
          if (ipod != null) {
            File notesDir = ipod.getNotes();
            if (notesDir.exists()) {
              File outDir = Util.newDir(notesDir,name());
              String fileName = title != null ? title : url;
              File outFile = new File(outDir,fileName);
              out = new PrintStream(new FileOutputStream(outFile));
              outTitle = fileName;
            }
          }
          
          if (out == null) {
            out = System.out;
            outTitle = "System.out";
          }
          note("Found title:"+title);
          out.println(title);
          out.println();
        }
      }

      //<p><b>Total Est. Time:</b>&nbsp;<span> 26 hours, 37 minutes</span></p>
      target = "Total Est. Time:</b>&nbsp;<span>";
      if (time == null && (index = line.indexOf(target)) != -1) {
        int ilt = line.indexOf("<",index+target.length()+1);
        if (ilt != -1) {
          time = line.substring(index+target.length(),ilt).trim();
          out.println("Time: " + time);
          note("Found time:"+time);
        }
      }

      //<p><b>Total Est. Distance:</b>&nbsp;<span>1758.11 miles</span></p>
      target = "Total Est. Distance:</b>&nbsp;<span>";
      if (dist == null && (index = line.indexOf(target)) != -1) {
        int ilt = line.indexOf("<",index+target.length()+1);
        if (ilt != -1) {
          dist = line.substring(index+target.length(),ilt).trim();
          out.println("Distance: " + dist);
          out.println();
          note("Found distance:"+dist);
        }
      }


      target = "<td class=\"num\">";
      if (line.indexOf(target) != -1) {
        directionsNext = true;
        continue;
      }

      target = ">";
      if (distanceNext && (index = line.indexOf(target)) != -1) {
        int ilt = line.indexOf("</td>",index+1);
        if (ilt != -1) {
          distance = line.substring(index+target.length(),ilt).trim();
          distanceNext = false;
          if (directions != null && distance != null && !distance.startsWith("<a name")) {
            String s = (num++) + ". (" + distance + ") " + directions;
            note(s);
            out.println(s);
          }
          directions = null;
          distance = null;
        }
      }

      target = ">";
      if (directionsNext && (index = line.indexOf(target)) != -1) {
        int ilt = line.indexOf("<",index+1);
        if (ilt != -1) {
          directions = line.substring(index+target.length(),ilt);
          directionsNext = false;
          distanceNext = true;
        }
      }
    }
    in.close();

    out.close();

    if (out != System.out) out.close();
    
    JOptionPane.showMessageDialog(null,"Written to " + outTitle);
  }

  private String urlFormat(String s) {
    if (s == null) return s;
    return URLEncoder.encode(s.toUpperCase());
  }

  private String createURL(AddressPanel from, AddressPanel to) {
    String fromAddress = urlFormat(from.getAddress());
    String fromCity    = urlFormat(from.getCity());
    String fromState   = urlFormat(from.getState());
    String fromZipcode = urlFormat(from.getZipcode());
    String toAddress   = urlFormat(to.getAddress());
    String toCity      = urlFormat(to.getCity());
    String toState     = urlFormat(to.getState());
    String toZipcode   = urlFormat(to.getZipcode());
    return "http://www.mapquest.com/directions/main.adp?go=1&do=nw&rmm=1&1gi=0&un=m&1da=-1.000000&1rc=L1AAA&cl=EN&qq=1ADqpk24ofCCarngIWwYK7lxP3G2UBX14%252b6%252bq8hcP%252bgHpXJE2QfNdh%252fZri0v%252bpY6lqVcA3Om1yRP8IqRW1AJCAtkLznqXnq9djMtpDwdEGNOBHRsGLEopHfaIpbaOCYO3b%252bZf8CfL6eU8ZYfP%252f6SC%252fPaSMPAwfeh%252f9m7lGLfeN5yDrEiLzHT77dA3DKUSNxPS5oQ765Abl2PtRc6LNwBMaMzU7rDxE%252bWyNs3%252brZXHlk%253d&ct=NA&r=f&1si=navt&rsres=1&1y=US&1ffi=&1l=k4kUaVQVLF3rtmY7LyMzPA%253d%253d&1g=Ps8F8eGAOxw4SohK0SWe9g%253d%253d&1pl=&1v=ADDRESS&1pn=&1a=" + fromAddress + "&1c=" + fromCity + "&1s=" + fromState + "&1z=" + fromZipcode + "&2y=US&2ffi=&2l=&2g=&2pl=&2v=&2n=&2pn=&2a=" + toAddress + "&2c=" + toCity + "&2s=" + toState + "&2z=" + toZipcode + "&panelbtn=2";
  }

  public static void main(String[] args) throws Exception {
    new MapquestDirections().find(new IPod(),Progress.DEFAULT);
    System.exit(0);
  }

}